package com.example.liuke.guangguang.videopicwebview;

import android.content.Context;
import android.media.MediaPlayer;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.webkit.JsResult;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import java.util.concurrent.CountDownLatch;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

public class WebVideoView extends WebView {
    private boolean playing;
    private WebVideoEventListener webVideoEventListener;
    private CountDownLatch countDownLatch;

    public WebVideoView(Context context) {
        super(context);
        init();
    }

    public WebVideoView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public WebVideoView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public WebVideoView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();
    }

    public WebVideoView(Context context, AttributeSet attrs, int defStyleAttr, boolean privateBrowsing) {
        super(context, attrs, defStyleAttr, privateBrowsing);
        init();
    }

    public void setWebVideoEventListener(WebVideoEventListener webVideoEventListener) {
        this.webVideoEventListener = webVideoEventListener;
    }
    /*Observable observable = Observable.create(new Observable.OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> subscriber) {
            subscriber.onNext("Hello");
            subscriber.onNext("Hi");
            subscriber.onNext("Aloha");
            subscriber.onCompleted();
        }
    });*/
    public void playVideo() {
        playing = true;
        Observable.create(new ObservableOnSubscribe<Object>() {//定义被观察者，被观察着执行耗时后台操作，需要异步执行的操作
            @Override
            public void subscribe(ObservableEmitter<Object> e) throws Exception {
                countDownLatch.await();
                e.onNext(true);
                e.onComplete();
            }
        })
                .subscribeOn(Schedulers.io())//被观察者在子线程
                .observeOn(AndroidSchedulers.mainThread())//观察者在主线程
                .subscribe(new Observer<Object>() {//观察者，
                               @Override
                               public void onError( Throwable e) {

                               }

                               @Override
                               public void onComplete() {

                               }

                               @Override
                               public void onSubscribe( Disposable d) {

                               }

                               @Override
                               public void onNext( Object o) {
                                   loadUrl("javascript:(function() {" +
                                           "var playVideo = function() {" +
                                           "var video = document.getElementsByTagName('video').item(0);" +
                                           "if(video) {" +
                                           "video.controls=false;" +
                                           "var listenEvent = function(e){" +
                                           "video.addEventListener(e,function(){" +
                                           "alert(e);" +
                                           "}, false);" +
                                           "};" +
                                           "listenEvent('playing');listenEvent('ended');listenEvent('error');" +
                                           "video.play();" +
                                           "} else {" +
                                           "setTimeout(function() { playVideo(); }, 500);" +
                                           "}" +
                                           "};" +
                                           "playVideo();" +
                                           "})()");
                               }
                           }
                );
    }

    public void pauseVideo() {
        playing = false;
        Observable.create(new ObservableOnSubscribe<Object>() {//定义被观察者
            @Override
            public void subscribe(ObservableEmitter<Object> e) throws Exception {
                countDownLatch.await();
                e.onNext(true);
                e.onComplete();//这里调用
            }
        })
                .subscribeOn(Schedulers.io())//被观察者在子线程
                .observeOn(AndroidSchedulers.mainThread())//观察者在主线程
                .subscribe(new Observer<Object>() {
                               @Override
                               public void onError( Throwable e) {

                               }

                               @Override
                               public void onComplete() {//这边具体实实现

                               }

                               @Override
                               public void onSubscribe( Disposable d) {

                               }

                               @Override
                               public void onNext( Object o) {
                                   loadUrl("javascript:(function() {" +
                                           "var pauseVideo = function() {" +
                                           "var video = document.getElementsByTagName('video').item(0);" +
                                           "if(video) {" +
                                           "video.pause();" +
                                           "} else {" +
                                           "setTimeout(function() { pauseVideo(); }, 500);" +
                                           "}" +
                                           "};" +
                                           "pauseVideo();" +
                                           "})()");
                               }
                           }
                );
    }

    private void init() {
        countDownLatch = new CountDownLatch(1);
        setWebViewClient(new WebVideoViewClient());
        setWebChromeClient(new WebChrome());
        WebSettings settings = getSettings();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        }
        settings.setJavaScriptEnabled(true);
        settings.setDatabaseEnabled(true);
        settings.setDomStorageEnabled(true);
        settings.setSaveFormData(false);
        settings.setAppCacheEnabled(true);
        settings.setUseWideViewPort(true);
        settings.setAllowFileAccess(true);//
        settings.setPluginState(WebSettings.PluginState.ON);

        /*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Boilerplate.DEBUG) {
            WebView.setWebContentsDebuggingEnabled(true);
        }*/
    }

    private class WebVideoViewClient extends WebViewClient {
        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            countDownLatch.countDown();
        }
    }

    private class WebChrome extends WebChromeClient implements MediaPlayer.OnCompletionListener {
        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            super.onProgressChanged(view, newProgress);
        }

        @Override
        public void onReceivedTitle(WebView view, String title) {
            super.onReceivedTitle(view, title);
        }

        @Override
        public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
            switch (message) {
                case "playing":
                    if (!playing) {
                        pauseVideo();
                    } else {
                        if (webVideoEventListener != null) {
                            webVideoEventListener.onPlaying();
                        }
                    }
                    break;
                case "ended":
                    if (webVideoEventListener != null) {
                        webVideoEventListener.onEnded();
                    }
                    break;
                case "error":
                    if (webVideoEventListener != null) {
                        webVideoEventListener.onError();
                    }
                    break;
            }
            result.confirm();
            return true;
        }

        @Override
        public void onCompletion(MediaPlayer mp) {
            if (mp != null) {
                if (mp.isPlaying()) {
                    mp.stop();
                }
                mp.reset();
                mp.release();
            }
        }
    }

    public interface WebVideoEventListener {
        void onPlaying();

        void onEnded();

        void onError();
    }
}
